home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / include / sun3.md / RCS / math-68881.h,v < prev    next >
Encoding:
Text File  |  1990-09-11  |  9.5 KB  |  441 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     90.09.11.14.50.17;  author kupfer;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     90.09.07.17.34.31;  author kupfer;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @Inline version of some math routines, using the 68881 coprocessor.
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @Second argument to modf points to a double, not an int.
  28. @
  29. text
  30. @
  31. /*******************************************************************
  32. *                                                                  *
  33. *  <math-68881.h>               last modified: March 22, 1989.     *
  34. *                                                                  *
  35. *  Copyright (C) 1989 by Matthew Self.                             *
  36. *  You may freely distribute verbatim copies of this software      *
  37. *  provided that this copyright notice is retained in all copies.  *
  38. *  You may distribute modifications to this software under the     *
  39. *  conditions above if you also clearly note such modifications    *
  40. *  with their author and date.                                     *
  41. *                                                                  *
  42. *  Note:  errno is not set to EDOM when domain errors occur for    *
  43. *  most of these functions.  Rather, it is assumed that the        *
  44. *  68881's OPERR exception will be enabled and handled             *
  45. *  appropriately by the operating system.  Similarly, overflow     *
  46. *  and underflow do not set errno to ERANGE.                       *
  47. *                                                                  *
  48. *  Send bugs to Matthew Self (self@@bayes.arc.nasa.gov).            *
  49. *                                                                  *
  50. *******************************************************************/
  51.  
  52. #ifndef __asm
  53. #define __asm asm               /* until new __asm is done */
  54. #endif
  55.  
  56. #ifndef __inline
  57. #define __inline inline         /* until new __inline is done */
  58. #endif
  59.  
  60. #include <errno.h>
  61.  
  62. #ifndef HUGE_VAL
  63. #define HUGE_VAL                                                        \
  64. ({                                                                      \
  65.   double huge_val;                                                      \
  66.                                                                         \
  67.   __asm ("fmove%.d #0x7ff0000000000000,%0"      /* Infinity */          \
  68.          : "=f" (huge_val)                                              \
  69.          : /* no inputs */);                                            \
  70.   huge_val;                                                             \
  71. })
  72. #endif
  73.  
  74. __inline static const double sin (double x)
  75. {
  76.   double value;
  77.  
  78.   __asm ("fsin%.x %1,%0"
  79.          : "=f" (value)
  80.          : "f" (x));
  81.   return value;
  82. }
  83.  
  84. __inline static const double cos (double x)
  85.   double value;
  86.  
  87.   __asm ("fcos%.x %1,%0"
  88.          : "=f" (value)
  89.          : "f" (x));
  90.   return value;
  91. }
  92.  
  93. __inline static const double tan (double x)
  94. {
  95.   double value;
  96.  
  97.   __asm ("ftan%.x %1,%0"
  98.          : "=f" (value)
  99.          : "f" (x));
  100.   return value;
  101. }
  102.  
  103. __inline static const double asin (double x)
  104. {
  105.   double value;
  106.  
  107.   __asm ("fasin%.x %1,%0"
  108.          : "=f" (value)
  109.          : "f" (x));
  110.   return value;
  111. }
  112.  
  113. __inline static const double acos (double x)
  114. {
  115.   double value;
  116.  
  117.   __asm ("facos%.x %1,%0"
  118.          : "=f" (value)
  119.          : "f" (x));
  120.   return value;
  121. }
  122.  
  123. __inline static const double atan (double x)
  124. {
  125.   double value;
  126.  
  127.   __asm ("fatan%.x %1,%0"
  128.          : "=f" (value)
  129.          : "f" (x));
  130.   return value;
  131. }
  132.  
  133. __inline static const double atan2 (double y, double x)
  134. {
  135.   double pi, pi_over_2;
  136.  
  137.   __asm ("fmovecr%.x %#0,%0"            /* extended precision pi */
  138.          : "=f" (pi)
  139.          : /* no inputs */ );
  140.   __asm ("fscale%.b %#-1,%0"            /* no loss of accuracy */
  141.          : "=f" (pi_over_2)
  142.          : "0" (pi));
  143.   if (x > 0)
  144.     {
  145.       if (y > 0)
  146.         {
  147.           if (x > y)
  148.             return atan (y / x);
  149.           else
  150.             return pi_over_2 - atan (x / y);
  151.         }
  152.       else
  153.         {
  154.           if (x > -y)
  155.             return atan (y / x);
  156.           else
  157.             return - pi_over_2 - atan (x / y);
  158.         }
  159.     }
  160.   else
  161.     {
  162.       if (y > 0)
  163.         {
  164.           if (-x > y)
  165.             return pi + atan (y / x);
  166.           else
  167.             return pi_over_2 - atan (x / y);
  168.         }
  169.       else
  170.         {
  171.           if (-x > -y)
  172.             return - pi + atan (y / x);
  173.           else if (y < 0)
  174.             return - pi_over_2 - atan (x / y);
  175.           else
  176.             {
  177.               double value;
  178.  
  179.               errno = EDOM;
  180.               __asm ("fmove%.d %#0rnan,%0"      /* quiet NaN */
  181.                      : "=f" (value)
  182.                      : /* no inputs */);
  183.               return value;
  184.             }
  185.         }
  186.     }
  187. }
  188.  
  189. __inline static const double sinh (double x)
  190. {
  191.   double value;
  192.  
  193.   __asm ("fsinh%.x %1,%0"
  194.          : "=f" (value)
  195.          : "f" (x));
  196.   return value;
  197. }
  198.  
  199. __inline static const double cosh (double x)
  200. {
  201.   double value;
  202.  
  203.   __asm ("fcosh%.x %1,%0"
  204.          : "=f" (value)
  205.          : "f" (x));
  206.   return value;
  207. }
  208.  
  209. __inline static const double tanh (double x)
  210. {
  211.   double value;
  212.  
  213.   __asm ("ftanh%.x %1,%0"
  214.          : "=f" (value)
  215.          : "f" (x));
  216.   return value;
  217. }
  218.  
  219. __inline static const double exp (double x)
  220. {
  221.   double value;
  222.  
  223.   __asm ("fetox%.x %1,%0"
  224.          : "=f" (value)
  225.          : "f" (x));
  226.   return value;
  227. }
  228.  
  229. __inline static const double log (double x)
  230. {
  231.   double value;
  232.  
  233.   __asm ("flogn%.x %1,%0"
  234.          : "=f" (value)
  235.          : "f" (x));
  236.   return value;
  237. }
  238.  
  239. __inline static const double log10 (double x)
  240. {
  241.   double value;
  242.  
  243.   __asm ("flog10%.x %1,%0"
  244.          : "=f" (value)
  245.          : "f" (x));
  246.   return value;
  247. }
  248.  
  249. __inline static const double pow (const double x, const double y)
  250. {
  251.   if (x > 0)
  252.     return exp (y * log (x));
  253.   else if (x == 0)
  254.     {
  255.       if (y > 0)
  256.         return 0.0;
  257.       else
  258.         {
  259.           double value;
  260.  
  261.           errno = EDOM;
  262.           __asm ("fmove%.d %#0rnan,%0"          /* quiet NaN */
  263.                  : "=f" (value)
  264.                  : /* no inputs */);
  265.           return value;
  266.         }
  267.     }
  268.   else
  269.     {
  270.       double temp;
  271.  
  272.       __asm ("fintrz%.x %1,%0"
  273.              : "=f" (temp)                      /* integer-valued float */
  274.              : "f" (y));
  275.       if (y == temp)
  276.         {
  277.           int i = (int) y;
  278.  
  279.           if (i & 1 == 0)                       /* even */
  280.             return exp (y * log (x));
  281.           else
  282.             return - exp (y * log (x));
  283.         }
  284.       else
  285.         {
  286.           double value;
  287.  
  288.           errno = EDOM;
  289.           __asm ("fmove%.d %#0rnan,%0"          /* quiet NaN */
  290.                  : "=f" (value)
  291.                  : /* no inputs */);
  292.           return value;
  293.         }
  294.     }
  295. }
  296.  
  297. __inline static const double sqrt (double x)
  298. {
  299.   double value;
  300.  
  301.   __asm ("fsqrt%.x %1,%0"
  302.          : "=f" (value)
  303.          : "f" (x));
  304.   return value;
  305. }
  306.  
  307. __inline static const double ceil (double x)
  308. {
  309.   int rounding_mode, round_up;
  310.   double value;
  311.  
  312.   __asm volatile ("fmove%.l fpcr,%0"
  313.                   : "=dm" (rounding_mode)
  314.                   : /* no inputs */ );
  315.   round_up = rounding_mode | 0x30;
  316.   __asm volatile ("fmove%.l %0,fpcr"
  317.                   : /* no outputs */
  318.                   : "dmi" (round_up));
  319.   __asm volatile ("fint%.x %1,%0"
  320.                   : "=f" (value)
  321.                   : "f" (x));
  322.   __asm volatile ("fmove%.l %0,fpcr"
  323.                   : /* no outputs */
  324.                   : "dmi" (rounding_mode));
  325.   return value;
  326. }
  327.  
  328. __inline static const double floor (double x)
  329. {
  330.   int rounding_mode, round_down;
  331.   double value;
  332.  
  333.   __asm volatile ("fmove%.l fpcr,%0"
  334.                   : "=dm" (rounding_mode)
  335.                   : /* no inputs */ );
  336.   round_down = (rounding_mode & ~0x10)
  337.                 | 0x20;
  338.   __asm volatile ("fmove%.l %0,fpcr"
  339.                   : /* no outputs */
  340.                   : "dmi" (round_down));
  341.   __asm volatile ("fint%.x %1,%0"
  342.                   : "=f" (value)
  343.                   : "f" (x));
  344.   __asm volatile ("fmove%.l %0,fpcr"
  345.                   : /* no outputs */
  346.                   : "dmi" (rounding_mode));
  347.   return value;
  348. }
  349.  
  350. #ifndef fabs
  351. __inline static const double fabs (double x)
  352. {
  353.   double value;
  354.  
  355.   __asm ("fabs%.x %1,%0"
  356.          : "=f" (value)
  357.          : "f" (x));
  358.   return value;
  359. }
  360. #endif
  361.  
  362. __inline static const double fmod (double x, double y)
  363. {
  364.   double value;
  365.  
  366.   __asm ("fmod%.x %2,%0"
  367.          : "=f" (value)
  368.          : "0" (x),
  369.            "f" (y));
  370.   return value;
  371. }
  372.  
  373. __inline static const double ldexp (double x, int n)
  374. {
  375.   double value;
  376.  
  377.   __asm ("fscale%.l %2,%0"
  378.          : "=f" (value)
  379.          : "0" (x),
  380.            "dmi" (n));
  381.   return value;
  382. }
  383.  
  384. __inline static double frexp (double x, int *exp)
  385. {
  386.   double float_exponent;
  387.   int int_exponent;
  388.   double mantissa;
  389.  
  390.   __asm ("fgetexp%.x %1,%0"
  391.          : "=f" (float_exponent)        /* integer-valued float */
  392.          : "f" (x));
  393.   int_exponent = (int) float_exponent;
  394.   __asm ("fgetmant%.x %1,%0"
  395.          : "=f" (mantissa)              /* 1.0 <= mantissa < 2.0 */
  396.          : "f" (x));
  397.   if (mantissa != 0)
  398.     {
  399.       __asm ("fscale%.b %#-1,%0"
  400.              : "=f" (mantissa)          /* mantissa /= 2.0 */
  401.              : "0" (mantissa));
  402.       int_exponent += 1;
  403.     }
  404.   *exp = int_exponent;
  405.   return mantissa;
  406. }
  407.  
  408. __inline static double modf (double x, double *ip)
  409.                 /* ip means "integer part" */
  410. {
  411.   __asm ("fintrz%.x %1,%0"
  412.          : "=f" (*ip)        /* integer-valued float */
  413.          : "f" (x));
  414.   return x - (*ip);
  415. }
  416.  
  417.  
  418. @
  419.  
  420.  
  421. 1.1
  422. log
  423. @Initial revision
  424. @
  425. text
  426. @d380 2
  427. a381 1
  428. __inline static double modf (double x, int *ip)
  429. a382 2
  430.   double temp;
  431.  
  432. d384 1
  433. a384 1
  434.          : "=f" (temp)                  /* integer-valued float */
  435. d386 1
  436. a386 2
  437.   *ip = (int) temp;
  438.   return x - temp;
  439. @
  440.